package com.fancy.application.sys.permission.service.impl;

import cn.hutool.core.util.StrUtil;
import com.fancy.application.common.constant.Constants;
import com.fancy.application.common.utils.RedisUtil;
import com.fancy.application.common.utils.UserUtil;
import com.fancy.application.sys.permission.entity.BaseModuleEntity;
import com.fancy.application.sys.permission.entity.Request;
import com.fancy.application.sys.permission.entity.SysPermissionResCategory;
import com.fancy.application.sys.permission.entity.SysPermissionUrl;
import com.fancy.application.sys.permission.service.ISysPermissionMatcher;
import com.fancy.application.sys.permission.service.ISysPermissionResCategoryService;
import com.fancy.application.sys.permission.service.ISysPermissionUrlService;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.util.AntPathMatcher;
import org.apache.shiro.util.PatternMatcher;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 加载权限信息
 */
@Log4j2
@Service("sysPermissionMatcher")
public class SysPermissionMatcher implements CommandLineRunner, ISysPermissionMatcher {
    private final String module_key = "moduleKey";      //模块存入redis的key值

    @Resource
    private ISysPermissionResCategoryService sysPermissionResCategoryService;
    @Resource
    private ISysPermissionUrlService sysPermissionUrlService;
    @Resource
    private RedisUtil redisUtil;



    /**
     *  暂时只控制url权限，不控制api权限
     * @param uri
     * @param method  zanbukongzhi
     * @return
     */
    public  Boolean  doMatch(String uri,String method){
        if(UserUtil.isAdmin())return true;
        PatternMatcher patternMatcher = new AntPathMatcher();
        Boolean urlAuthFlag = Boolean.TRUE;
        if(StrUtil.isNotEmpty(uri)){
            List<SysPermissionResCategory> sysPermissionResCategories = (List<SysPermissionResCategory>) redisUtil.get(Constants.RES_CATE_KEY);
            Optional<SysPermissionResCategory> optional = sysPermissionResCategories.stream()
                    .filter(sysPermissionResCategory -> {
                        return StrUtil.startWith(uri, sysPermissionResCategory.getFdModulePath());
                    }).findFirst();
            if(optional.isPresent()){
                SysPermissionResCategory sysPermissionResCategory = optional.get();
                String fdModuleId = sysPermissionResCategory.getFdModulePath();
                List<SysPermissionUrl> urls = (List<SysPermissionUrl>) redisUtil.get(fdModuleId);
                List<SysPermissionUrl> parentUrlList = urls.stream()
                        .filter(sysPermissionUrl -> StrUtil.isEmpty(sysPermissionUrl.getFdParentId())).collect(Collectors.toList());
                Optional<SysPermissionUrl> parentOptional =  urls.stream().filter(sysPermissionUrl ->
                        patternMatcher.matches(sysPermissionUrl.getFdPath(), uri)).findFirst(); //查找父类的url验证，如果验证失败，则直接失败
                if(parentOptional.isPresent()){
                    SysPermissionUrl parentUrl = parentOptional.get();
                    if(!UserUtil.isPermitted(parentUrl.getFdExpression())) return false;
                    String fdParentId = parentUrl.getFdParentId();
                    List<SysPermissionUrl> childUrlList =  parentUrlList.stream().filter(sysPermissionUrl ->
                            StrUtil.equals(sysPermissionUrl.getFdParentId(),fdParentId)
                            ).collect(Collectors.toList());
                    Optional<SysPermissionUrl>  childOptional =  childUrlList.stream().filter(sysPermissionUrl ->
                            patternMatcher.matches(sysPermissionUrl.getFdPath(), uri)&&StrUtil.equals(sysPermissionUrl.getFdMethod(),method)
                    ).findFirst(); //查找子类的url验证，如果验证失败，则失败
                    if(childOptional.isPresent()){
                        SysPermissionUrl childUrl = parentOptional.get();
                        urlAuthFlag = UserUtil.isPermitted(parentUrl.getFdExpression());
                    }
                }
            }
        }
        return urlAuthFlag;
    }

    @Override
    public void run(String... args) {
        //启动加载模块信息和url信息
        List<BaseModuleEntity> baseModuleEntities = (List<BaseModuleEntity>) redisUtil.get(Constants.MODULE_KEY);   //设置模块列表
        List<SysPermissionResCategory> sysPermissionResCategories = new ArrayList<>();
        baseModuleEntities.forEach(baseModuleEntity -> {
            String path = baseModuleEntity.getFdPath();
            SysPermissionResCategory category = new SysPermissionResCategory();
            category.setFdName(baseModuleEntity.getFdName());
            category.setFdModulePath(baseModuleEntity.getFdPath());
            sysPermissionResCategories.add(category);
        });
        redisUtil.delKeys(Constants.RES_CATE_KEY);
        redisUtil.set(Constants.RES_CATE_KEY,sysPermissionResCategories);
        List<SysPermissionUrl> urls = new ArrayList<>();
        baseModuleEntities.forEach(baseModuleEntity -> {
            List<Request> requests = baseModuleEntity.getRequests();
            requests.forEach(request -> {
                SysPermissionUrl url = new SysPermissionUrl();
                List<Request> children = request.getChildren();
                url.setFdPath(request.getPath());
                url.setFdMethod(request.getMethod());
                url.setFdExpression(request.getRole());
                urls.add(url);
                children.forEach(req ->{
                    SysPermissionUrl sysPermissionUrl = new SysPermissionUrl();
                    sysPermissionUrl.setFdPath(req.getPath());
                    sysPermissionUrl.setFdMethod(req.getMethod());
                    sysPermissionUrl.setFdExpression(req.getRole());
                    urls.add(sysPermissionUrl);
                });
            });
            redisUtil.set(baseModuleEntity.getFdPath(),urls);
        });
        log.info("模块列表加载成功!");
    }
}
